package com.gitee.qdbp.jdbc.sql.parse;

import java.lang.reflect.Constructor;
import com.gitee.qdbp.jdbc.api.SqlBoot;
import com.gitee.qdbp.staticize.exception.TagException;
import com.gitee.qdbp.staticize.tags.base.ITag;
import com.gitee.qdbp.staticize.tags.base.TagFactory;
import com.gitee.qdbp.tools.utils.ReflectTools;

class SqlTagFactory implements TagFactory {

    private final SqlBoot sqlBoot;

    public SqlTagFactory(SqlBoot sqlBoot) {
        this.sqlBoot = sqlBoot;
    }

    @Override
    public <T extends ITag> T newTagInstance(Class<T> clazz) {
        Class<?>[] params = new Class<?>[] { SqlBoot.class };
        // 先查找带有SqlBoot参数的构造函数
        Constructor<T> constructor;
        try {
            constructor = clazz.getConstructor(params);
        } catch (NoSuchMethodException e) {
            constructor = null;
        } catch (SecurityException e) {
            String signature = ReflectTools.getMethodLogSignature(clazz, clazz.getSimpleName(), params);
            throw new TagException("Failed to get constructor: " + signature, e);
        }
        if (constructor != null) {
            // 带SqlBoot的构造函数不为空
            try {
                Object[] args = new Object[] { sqlBoot };
                return constructor.newInstance(args);
            } catch (Exception e) {
                String signature = ReflectTools.getMethodLogSignature(clazz, clazz.getSimpleName(), params);
                throw new TagException("Failed to create tag class instance: " + signature, e);
            }
        } else {
            // 调用默认构造函数
            try {
                return clazz.newInstance();
            } catch (Exception e) {
                throw new TagException("Failed to create tag class instance: " + clazz.getName(), e);
            }
        }
    }
}
